package com.hjh.usb.accessory.communication

import java.io.ByteArrayOutputStream

/**
 * 用于 AOA 报文处理的工具方法集，包括字节转换、包头构建、CRC 校验等。
 */
object PacketUtils {
    val PACKET_HEADER = byteArrayOf(0xAA.toByte(), 0x55.toByte(), 0xAA.toByte(), 0x55.toByte())
    val ACK_HEADER = byteArrayOf(0x55.toByte(), 0xAA.toByte(), 0x55.toByte(), 0xAA.toByte())

    fun Long.toBytes4(): ByteArray = ByteArray(4) {
        (this shr (8 * (3 - it)) and 0xFF).toByte()
    }

    fun Int.toBytes4(): ByteArray = this.toLong().toBytes4()

    fun ByteArray.toIntFromBytes(): Int {
        var value = 0
        forEach { byte ->
            value = (value shl 8) or (byte.toInt() and 0xFF)
        }
        return value
    }

    fun buildDataPacket(
        fileSize: Long,
        chunkIndex: Int,
        data: ByteArray,
        length: Int
    ): ByteArray {
        return ByteArrayOutputStream().apply {
            write(PACKET_HEADER)
            write(fileSize.toBytes4())
            write(chunkIndex.toBytes4())
            write(length.toBytes4())
            write(data, 0, length)
            write(calculateCrc16())
        }.toByteArray()
    }

    fun buildEndPacket(): ByteArray {
        return PACKET_HEADER +
                (-1).toBytes4() +
                0.toBytes4() +
                0.toBytes4()
    }

    fun parseChunkIndex(packet: ByteArray): Int {
        return packet.copyOfRange(8, 12).toIntFromBytes()
    }

    fun parseAckChunkIndex(ackPacket: ByteArray): Int {
        return ackPacket.copyOfRange(4, 8).toIntFromBytes()
    }

    fun isAckPacket(data: ByteArray): Boolean {
        return data.size >= 4 &&
                data[0] == ACK_HEADER[0] &&
                data[1] == ACK_HEADER[1] &&
                data[2] == ACK_HEADER[2] &&
                data[3] == ACK_HEADER[3]
    }

    fun calculateCrc16(): ByteArray {
        // 简化实现，实际项目应替换为标准CRC16算法
        val crc = 0
        return byteArrayOf(
            (crc shr 8).toByte(),
            crc.toByte()
        )
    }
}
